﻿using System;
using System.Threading;
using WebSocket4Net;

namespace Core.ItoolQueue
{
    internal class BaseSocketClient : IDisposable
    {
        #region 向外传递数据事件

        /// <summary>
        /// 打开事件
        /// </summary>
        public event Action Opened;

        /// <summary>
        /// 关闭事件
        /// </summary>
        public event Action Closed;

        /// <summary>
        /// 接受消息
        /// </summary>
        public event Action<string> MessageReceived;


        #endregion

        /// <summary>
        /// 当前服务实例
        /// </summary>
        WebSocket WSocketClientInstance;

        /// <summary>
        /// 守护线程
        /// </summary>
        Thread GuardThread;

        /// <summary>
        /// 是否运行
        /// </summary>
        bool IsRunning = true;

        /// <summary>
        /// 服务地址地址
        /// </summary>
        public string ServerPath { get; set; }

        public BaseSocketClient(string url)
        {
            ServerPath = url;
            this.WSocketClientInstance = new WebSocket(url);
            this.WSocketClientInstance.Opened += WebSocket_Opened;
            this.WSocketClientInstance.Closed += WebSocket_Closed;
            this.WSocketClientInstance.MessageReceived += WebSocket_MessageReceived;
        }

        void WebSocket_Closed(object sender, EventArgs e)
        {
            if (this.Closed != null)
            {
                this.Closed.Invoke();
            }
        }

        void WebSocket_Opened(object sender, EventArgs e)
        {
            if (this.Opened != null)
            {
                this.Opened.Invoke();
            }
        }

        void WebSocket_MessageReceived(object sender, MessageReceivedEventArgs e)
        {
            if (this.MessageReceived != null)
            {
                this.MessageReceived.Invoke(e.Message);
            }
        }

        /// <summary>
        /// 打开链接
        /// </summary>
        public void Open()
        {
            try
            {
                this.WSocketClientInstance.Open();
                this.IsRunning = true;
                this.GuardThread = new Thread(new ThreadStart(CheckConnection));
                this.GuardThread.Start();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        private void CheckConnection()
        {
            do
            {
                try
                {
                    if (this.WSocketClientInstance.State != WebSocketState.Open 
                        && this.WSocketClientInstance.State != WebSocketState.Connecting)
                    {
                        this.WSocketClientInstance.Close();
                        this.WSocketClientInstance.Open();
                        Console.WriteLine("尝试重连");
                    }
                }
                catch (Exception ex)
                {
                    
                }

                Thread.Sleep(2000);

            } while (this.IsRunning);
        }


        /// <summary>
        /// 关闭链接释放资源
        /// </summary>
        public void Dispose()
        {
            this.IsRunning = false;
            try
            {
                GuardThread.Abort();
            }
            catch
            {

            }
            this.WSocketClientInstance.Close();
            this.WSocketClientInstance.Dispose();
            this.WSocketClientInstance = null;
        }
    }
}
